/*
 * Copyright (c) 2007-2008, Thomas Krause (tho.krause@gmail.com)
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of gidoo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without specific
 *       prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.gidoo.cms.editor.edit;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.gidoo.cms.data.Folder;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.gidoo.cms.GidooCMS;
import org.gidoo.cms.data.Page;
import org.gidoo.cms.dbconnection.DatabaseConnectionException;
import org.gidoo.cms.editor.EditorPage;
import org.gidoo.cms.login.GidooCMSAuthenticatedWebSession;
import org.gidoo.cms.view.XSLTTransformFailedException;
import org.gidoo.wickettools.xmledit.XMLEditor;
import org.xml.sax.SAXException;

/**
 *
 * @author thomas
 */
public class EditPanel extends Panel
{
  Folder theFolder;
  
  Form formEdit;
  
  Label lblStatus;
  TextField txtTitle;
  XMLEditor editor;
  AjaxButton btOk;
  Button btAbort;
 
  AjaxSubmitLink lnkPreview;
  ModalWindow window;
  
  EditorPage parentPage;
  
  public EditPanel(String id, Folder folder, EditorPage parent)
  {
    super(id);
   
    this.setOutputMarkupId(true);
    
    formEdit =new Form("formEdit");
    add(formEdit);
    
    lblStatus = new Label("lblStatus", new Model(""));
    
    editor = new XMLEditor("editor", getSchemaFile());
    
    txtTitle = new TextField("txtTitle", new Model(""));
    
    
    btOk =new AjaxButton("btOk")
    {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form)
      {
        updateDB(target);
      }
    };
    btOk.setModel(new Model(getString("ok")));
    
    btAbort = new Button("btAbort");
    btAbort.setModel(new Model(getString("abort")));
    
    lnkPreview = new AjaxSubmitLink("lnkPreview") 
    {
      @Override
      protected void onSubmit(AjaxRequestTarget target, Form form)
      {
        final String content = editor.getText();
        if(validate(content))
        {
        
          window.setPageCreator(new ModalWindow.PageCreator() 
          {

            public org.apache.wicket.Page createPage()
            {            
              try
              {              
                return new PreviewPage(content);
              }
              catch (XSLTTransformFailedException ex)
              {
                Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, null, ex);
                error(getString("validationfailed"));
              }
              return null;
              
            }
          });
          
          window.setTitle(getString("preview") + ": " + txtTitle.getModelObjectAsString());
          window.show(target);
        }
        else
        {
          error(getString("validationfailed"));
        }
      
        
        target.addComponent(parentPage.getFeedbackPanel());
      }
    };
    
    formEdit.add(editor);
    formEdit.add(txtTitle);
    formEdit.add(btOk);
    formEdit.add(btAbort);
    formEdit.add(lnkPreview);
    
    window = new ModalWindow("window");
    add(window);
    
    add(lblStatus);
    
    
    updateDataAndView(folder, parent);
    
    
  }
  
  private File getSchemaFile()
  {
    File f = new File(((GidooCMS) getApplication()).getRealPathToContext() 
      + "/WEB-INF/xml/gidooml.xsd");
    if(!f.exists())
    {
      error(getString("missingschemafile"));
      return null;
    }
    
    return f;
    
  }
  
  private boolean validate(String newContent)
  {
    
    try
    {
      File f = getSchemaFile();
      if(f == null)
      {
        return false;
      }
      Schema s = 
        SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(f);

      StringReader reader = new StringReader(newContent);

      Validator validator = s.newValidator();
      StreamSource source = new StreamSource(reader);
      validator.validate(source);

    }
    catch (SAXException ex)
    {
      Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("validationfailed"));
      error(ex.getLocalizedMessage());
      return false;
    }
    catch(IOException ex)
    {
      Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("error"));
      return false;
    }
    
    return true;
  }
  
  public void updateDB(AjaxRequestTarget target)
  {
    if (theFolder == null || target == null)
    {
      return;
    }
   
    target.addComponent(parentPage.getFeedbackPanel());
    target.addComponent(parentPage.getTreeNav());

    String newContent = editor.getText();

    if(!"".equals(newContent))
    {
      if(!validate(newContent))
        return;
    }
    
    try
    {
      GidooCMSAuthenticatedWebSession session = (GidooCMSAuthenticatedWebSession) getSession();
      Page newPage = new Page();
      newPage.setCreatedBy(session.getUserInfo());
      newPage.setCreatedTime(Calendar.getInstance().getTime());

      newPage.setContentAsXML(newContent);
      newPage.setTitle(txtTitle.getModelObjectAsString());

      if (theFolder.getPageWaitingForPublisher() != null)
      {
        if (theFolder.getHistory() == null)
        {
          theFolder.setHistory(new LinkedList<Page>());
        }
        theFolder.getHistory().add(theFolder.getPageWaitingForPublisher());
      }
      theFolder.setPageWaitingForPublisher(newPage);


      ((GidooCMS) getApplication()).getDb().persist(newPage);
      theFolder = (Folder) ((GidooCMS) getApplication()).getDb().merge(theFolder);

      lblStatus.setModelObject(getString("waitingforpublisher"));
    }
    catch (DatabaseConnectionException ex)
    {
      Logger.getLogger(EditPanel.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("dberror"));
    }


    parentPage.updateDataAndView();

  }

  public void updateDataAndView(Folder folder, EditorPage parent)
  {
    if(parent == null)
    {
      throw new IllegalArgumentException();
    }
    
    theFolder = folder;
    parentPage = parent;
    
    editor.setEnabled(true);
    btAbort.setEnabled(true);
    btOk.setEnabled(true);
    txtTitle.setEnabled(true);
    lnkPreview.setEnabled(true);
    
    if(folder == null)
    {
      lblStatus.setModelObject(getString("null"));
      editor.setEnabled(false);
      btAbort.setEnabled(false);
      btOk.setEnabled(false);
      txtTitle.setEnabled(false);
      lnkPreview.setEnabled(false);
    }
    else if(folder.getPageWaitingForPublisher() != null)
    {
      lblStatus.setModelObject(getString("waitingforpublisher"));
      editor.setText(folder.getPageWaitingForPublisher().getContentAsXML());
      txtTitle.setModelObject(folder.getPageWaitingForPublisher().getTitle());
    }
    else if(folder.getPublishedPage() != null)
    {
      lblStatus.setModelObject(getString("published"));
      editor.setText(folder.getPublishedPage().getContentAsXML());
      txtTitle.setModelObject(folder.getPublishedPage().getTitle());
    }
    else
    {
      lblStatus.setModelObject(getString("isnew"));
      editor.setEnabled(true);
      
      if("".equals(editor.getText()))
      {
        editor.setText(getString("defaultxml"));
      }
    }
      
  }
  
}
